package com.dongrj.framework.core.instance;

import com.dongrj.framework.core.exception.Assert;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

@Slf4j
public final class InstanceFactory {

    private static final ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>();

    /**
     * 获取单例实例
     *
     * @param tClass    单例实例类型
     * @param tSupplier 单例提供操作
     */
    public static <T> T getInstance(Class<T> tClass, Supplier<T> tSupplier) {
        T singleton = getInstance(tClass, "singleton", tSupplier);
        log.warn("正在获取单例对象:{},{}", tClass.getName(), singleton);
        return singleton;
    }


    /**
     * 获取实例
     *
     * @param tClass              实例类型
     * @param instanceUniqueValue 实例的唯一值
     * @param tSupplier           实例提供操作
     */
    public static <T> T getInstance(Class<T> tClass, Object instanceUniqueValue, Supplier<T> tSupplier) {
        String name = tClass.getName();
        Assert.notEmpty(instanceUniqueValue, "value 不能为空!");
        String sv = String.valueOf(instanceUniqueValue);
        return getInstance(name + ":" + sv, tSupplier);
    }


    /**
     * 获取实例
     *
     * @param instanceKey 实例缓存key
     * @param tSupplier   实例提供操作
     */
    public static <T> T getInstance(String instanceKey, Supplier<T> tSupplier) {
        if (cache.containsKey(instanceKey)) {
            return (T) cache.get(instanceKey);
        }
        T t = tSupplier.get();
        if (t == null) {
            throw new RuntimeException("提供的对象不能为空!");
        }
        log.info("创建对象:{},{}", instanceKey, t);
        cache.put(instanceKey, t);
        return t;
    }
}
